import {NodeSingular, EdgeSingular, Core, EventObject} from "cytoscape";
import {notifications} from "@mantine/notifications";

const HOVER_COLOR = "#F05A7E";
const SELECTED_NODE_BORDER_COLOR = "#9E1B32";
const SELECTED_NODE_BORDER_WIDTH = 3;
const SELECTED_EDGE_LINE_COLOR = "#d80028";
let selectedNode: NodeSingular | null = null; // 当前选中的节点
let selectedEdge: EdgeSingular | null = null; // 当前选中的边

// 清除全部样式，众生平等
const clearAllStyles = (cy: Core) => {
  cy.elements().style({
    "background-color": "",
    "line-color": "",
    "border-color": "",
    "border-width": 0,
  });
};

export const addCyEvents = (cy: Core) => {
  // 一、鼠标移入节点
  cy.on("mouseover", "node", (e: EventObject) => {
    const node = e.target;
    if (!selectedNode) {
      const neighbors = node.neighborhood();
      const all = neighbors.add(node);
      all.style({
        "background-color": HOVER_COLOR,
        "line-color": HOVER_COLOR,
      });
    }
  });
  // 二、鼠标移出节点
  cy.on("mouseout", "node", (e: EventObject) => {
    const node = e.target;
    if (!selectedNode) clearAllStyles(cy);
  });
  // 三、鼠标移入边
  cy.on("mouseover", "edge", (e: EventObject) => {
    const edge = e.target;
    if (!selectedEdge) {
      const connectedNodes = edge.connectedNodes();
      const all = connectedNodes.add(edge);
      all.style({
        "background-color": HOVER_COLOR,
        "line-color": HOVER_COLOR,
      });
    }
  });
  // 四、鼠标移出边
  cy.on("mouseout", "edge", (e: EventObject) => {
    const edge = e.target;
    if (!selectedEdge) clearAllStyles(cy);
  });

  // 五、鼠标点击节点，使节点处于选中状态
  cy.on("tap", "node", (e: EventObject) => {
    const node = e.target;
    // 若当前节点已选中，则不重新渲染
    if (node.selected()) return;
    // 如果之前有节点被选中，则清除之前节点的选中状态
    if (selectedNode) clearAllStyles(cy);
    // 记录当前选中的节点
    selectedNode = node;
    // 设置当前节点和邻居的样式
    const neighbors = node.neighborhood();

    neighbors.style({
      "background-color": HOVER_COLOR,
      "line-color": HOVER_COLOR,
    });

    node.style({
      "background-color": HOVER_COLOR,
      "border-color": SELECTED_NODE_BORDER_COLOR,
      "border-width": SELECTED_NODE_BORDER_WIDTH,
    });

    // 提示信息
    // notifications.show({
    //   color: "green",
    //   message: `点击了节点: ${node.id()}`,
    //   autoClose: 1500,
    // });
  });

  // 六、鼠标点击边，使边处于选中状态
  cy.on("tap", "edge", (e: EventObject) => {
    const edge = e.target;
    // 若当前边已选中，则不重新渲染
    if (edge.selected()) return;
    // 如果之前有边被选中，则清除之前边的选中状态
    if (selectedEdge) clearAllStyles(cy);
    // 记录当前选中的边
    selectedEdge = edge;
    // 设置当前边和连接节点的样式
    const connectedNodes = edge.connectedNodes();
    const all = connectedNodes.add(edge);
    all.style({
      "background-color": HOVER_COLOR,
      "line-color": SELECTED_EDGE_LINE_COLOR,
    });

    // 提示信息
    // notifications.show({
    //   color: "blue",
    //   message: `点击了边: ${edge.id()}`,
    //   autoClose: 1500,
    // });
  });

  // 七、鼠标点击空白区域，清除选中状态
  cy.on("tap", (e: EventObject) => {
    // 点击的是空白区域并且当前选有选中节点
    if (e.target === cy) {
      if (selectedNode) {
        clearAllStyles(cy); //清除所有样式
        selectedNode = null; // 清除选中节点
      }
      if (selectedEdge) {
        clearAllStyles(cy); //清除所有样式
        selectedEdge = null; // 清除选中节点
      }
    }
  });

  // 八、画布尺寸变化时 居中
  cy.on("resize", () => cy.center());
  cy.on("layoutstop", () => cy.center());
};
